summaryrefslogtreecommitdiff
path: root/src/plugins/projectexplorer/abi.cpp
diff options
context:
space:
mode:
authorTobias Hunger <tobias.hunger@nokia.com>2011-03-03 11:29:07 +0100
committerTobias Hunger <tobias.hunger@nokia.com>2011-03-03 16:35:04 +0100
commitcb7cca793a02f52d5b63149bae43526ae609442a (patch)
treeefa9c1581cf93c65d208a4a2598cfa47efa2d42f /src/plugins/projectexplorer/abi.cpp
parentf20591e727e446aa1b82f767b9c018114ec166b3 (diff)
downloadqt-creator-cb7cca793a02f52d5b63149bae43526ae609442a.tar.gz
Detect ABIs of static libs
Diffstat (limited to 'src/plugins/projectexplorer/abi.cpp')
-rw-r--r--src/plugins/projectexplorer/abi.cpp94
1 files changed, 56 insertions, 38 deletions
diff --git a/src/plugins/projectexplorer/abi.cpp b/src/plugins/projectexplorer/abi.cpp
index ea0ad8fe7d..3589955063 100644
--- a/src/plugins/projectexplorer/abi.cpp
+++ b/src/plugins/projectexplorer/abi.cpp
@@ -34,11 +34,11 @@
#include "abi.h"
#include <QtCore/QCoreApplication>
+#include <QtCore/QDebug>
#include <QtCore/QFile>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QSysInfo>
-#include <QtCore/QDebug>
namespace ProjectExplorer {
@@ -63,6 +63,48 @@ static Abi macAbiForCpu(quint32 type) {
}
}
+static QList<Abi> parseCoffHeader(const QByteArray &data)
+{
+ QList<Abi> result;
+ if (data.size() < 20)
+ return result;
+
+ Abi::Architecture arch = Abi::UnknownArchitecture;
+ Abi::OSFlavor flavor = Abi::UnknownFlavor;
+ int width = 0;
+
+ // Get machine field from COFF file header
+ quint16 machine = (data.at(1) << 8) + data.at(0);
+ switch (machine) {
+ case 0x8664: // x86_64
+ arch = Abi::X86Architecture;
+ width = 64;
+ break;
+ case 0x014c: // i386
+ arch = Abi::X86Architecture;
+ width = 32;
+ break;
+ case 0x0200: // ia64
+ arch = Abi::ItaniumArchitecture;
+ width = 64;
+ break;
+ }
+
+ if (data.size() >= 68) {
+ // Get Major and Minor Image Version from optional header fields
+ quint32 image = (data.at(67) << 24) + (data.at(66) << 16) + (data.at(65) << 8) + data.at(64);
+ if (image == 1) // Image is 1 for mingw and higher for MSVC (4.something in some encoding)
+ flavor = Abi::WindowsMSysFlavor;
+ else
+ flavor = Abi::WindowsMsvcFlavor;
+ }
+
+ if (arch != Abi::UnknownArchitecture && width != 0)
+ result.append(Abi(arch, Abi::WindowsOS, flavor, Abi::PEFormat, width));
+
+ return result;
+}
+
static QList<Abi> abiOf(const QByteArray &data)
{
QList<Abi> result;
@@ -119,39 +161,8 @@ static QList<Abi> abiOf(const QByteArray &data)
// Windows PE
// Windows can have its magic bytes everywhere...
int pePos = data.indexOf(QByteArray("PE\0\0", 4));
- if (pePos >= 0 && pePos + 72 < data.size()) {
- Abi::Architecture arch = Abi::UnknownArchitecture;
- Abi::OSFlavor flavor = Abi::UnknownFlavor;
- int width = 0;
-
- // Get machine field from COFF file header
- quint16 machine = (data.at(pePos + 5) << 8) + data.at(pePos + 4);
- switch (machine) {
- case 0x8664: // x86_64
- arch = Abi::X86Architecture;
- width = 64;
- break;
- case 0x014c: // i386
- arch = Abi::X86Architecture;
- width = 32;
- break;
- case 0x0200: // ia64
- arch = Abi::ItaniumArchitecture;
- width = 64;
- break;
- }
-
- // Get Major and Minor Image Version from optional header fields
- quint32 image = (data.at(pePos + 71) << 24) + (data.at(pePos + 70) << 16)
- + (data.at(pePos + 69) << 8) + data.at(pePos + 68);
- if (image == 1) // Image is 1 for mingw and 4.something for MSVC
- flavor = Abi::WindowsMSysFlavor;
- else
- flavor = Abi::WindowsMsvcFlavor;
-
- if (arch != Abi::UnknownArchitecture && flavor != Abi::UnknownFlavor && width != 0)
- result.append(Abi(arch, Abi::WindowsOS, flavor, Abi::PEFormat, width));
- }
+ if (pePos >= 0)
+ result = parseCoffHeader(data.mid(pePos + 4));
}
return result;
}
@@ -454,6 +465,8 @@ QList<Abi> Abi::abisOfBinary(const QString &path)
if (!f.exists())
return result;
+ bool windowsStatic = path.endsWith(QLatin1String(".lib"));
+
f.open(QFile::ReadOnly);
QByteArray data = f.read(1024);
if (data.size() >= 67
@@ -467,7 +480,7 @@ QList<Abi> Abi::abisOfBinary(const QString &path)
quint64 offset = 8;
while (!data.isEmpty()) {
- if (data.at(58) != 0x60 || data.at(59) != 0x0a) {
+ if ((data.at(58) != 0x60 || data.at(59) != 0x0a)) {
qWarning() << path << ": Thought it was an ar-file, but it is not!";
break;
}
@@ -478,13 +491,18 @@ QList<Abi> Abi::abisOfBinary(const QString &path)
fileNameOffset = fileName.mid(3).toInt();
const QString fileLength = QString::fromAscii(data.mid(48, 10));
- data = data.mid(60 + fileNameOffset);
+ int toSkip = 60 + fileNameOffset;
offset += fileLength.toInt() + 60 /* header */;
- result = abiOf(data);
+ if (windowsStatic) {
+ if (fileName == QLatin1String("/0 "))
+ result = parseCoffHeader(data.mid(toSkip, 20));
+ } else {
+ result = abiOf(data.mid(toSkip));
+ }
if (!result.isEmpty())
break;
- f.seek(offset);
+ f.seek(offset + (offset % 2)); // ar is 2 byte alligned
data = f.read(1024);
}
} else {