forked from OSchip/llvm-project
Support --build-id=0x<hexstring>.
If you specify the option in the form of --build-id=0x<hexstring>, that hexstring is set as a build ID. We observed that the feature is actually in use in some builds, so we want this feature. llvm-svn: 269495
This commit is contained in:
parent
abbc2ac231
commit
9194db78fb
|
|
@ -30,7 +30,7 @@ enum ELFKind {
|
|||
ELF64BEKind
|
||||
};
|
||||
|
||||
enum class BuildIdKind { None, Fnv1, Md5, Sha1 };
|
||||
enum class BuildIdKind { None, Fnv1, Md5, Sha1, Hexstring };
|
||||
|
||||
// This struct contains the global configuration for the linker.
|
||||
// Most fields are direct mapping from the command line options
|
||||
|
|
@ -53,6 +53,7 @@ struct Configuration {
|
|||
std::vector<llvm::StringRef> SearchPaths;
|
||||
std::vector<llvm::StringRef> Undefined;
|
||||
std::vector<llvm::StringRef> VersionScriptGlobals;
|
||||
std::vector<uint8_t> BuildIdVector;
|
||||
bool AllowMultipleDefinition;
|
||||
bool AsNeeded = false;
|
||||
bool Bsymbolic;
|
||||
|
|
|
|||
|
|
@ -386,14 +386,18 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
|
|||
Config->BuildId = BuildIdKind::Fnv1;
|
||||
if (auto *Arg = Args.getLastArg(OPT_build_id_eq)) {
|
||||
StringRef S = Arg->getValue();
|
||||
if (S == "md5")
|
||||
if (S == "md5") {
|
||||
Config->BuildId = BuildIdKind::Md5;
|
||||
else if (S == "sha1")
|
||||
} else if (S == "sha1") {
|
||||
Config->BuildId = BuildIdKind::Sha1;
|
||||
else if (S == "none")
|
||||
} else if (S == "none") {
|
||||
Config->BuildId = BuildIdKind::None;
|
||||
else
|
||||
} else if (S.startswith("0x")) {
|
||||
Config->BuildId = BuildIdKind::Hexstring;
|
||||
Config->BuildIdVector = parseHexstring(S.substr(2));
|
||||
} else {
|
||||
error("unknown --build-id style: " + S);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto *Arg : Args.filtered(OPT_undefined))
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ enum {
|
|||
|
||||
void printHelp(const char *Argv0);
|
||||
void printVersion();
|
||||
std::vector<uint8_t> parseHexstring(StringRef S);
|
||||
|
||||
void createResponseFile(const llvm::opt::InputArgList &Args);
|
||||
void maybeCopyInputFile(StringRef Path, StringRef Buffer);
|
||||
|
|
|
|||
|
|
@ -88,6 +88,22 @@ void elf::printVersion() {
|
|||
outs() << "\n";
|
||||
}
|
||||
|
||||
// Converts a hex string (e.g. "0x123456") to a vector.
|
||||
std::vector<uint8_t> elf::parseHexstring(StringRef S) {
|
||||
if (S.find_first_not_of("0123456789abcdefABCDEF") != StringRef::npos ||
|
||||
S.size() % 2) {
|
||||
error("malformed hexstring: " + S);
|
||||
return {};
|
||||
}
|
||||
std::vector<uint8_t> V;
|
||||
for (; !S.empty(); S = S.substr(2)) {
|
||||
int I;
|
||||
S.substr(0, 2).getAsInteger(16, I);
|
||||
V.push_back(I);
|
||||
}
|
||||
return V;
|
||||
}
|
||||
|
||||
// Makes a given pathname an absolute path first, and then remove
|
||||
// beginning /. For example, "../foo.o" is converted to "home/john/foo.o",
|
||||
// assuming that the current directory is "/home/john/bar".
|
||||
|
|
|
|||
|
|
@ -1686,6 +1686,16 @@ void BuildIdSha1<ELFT>::writeBuildId(ArrayRef<ArrayRef<uint8_t>> Bufs) {
|
|||
memcpy(this->HashBuf, Hash.final().data(), 20);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
BuildIdHexstring<ELFT>::BuildIdHexstring()
|
||||
: BuildIdSection<ELFT>(Config->BuildIdVector.size()) {}
|
||||
|
||||
template <class ELFT>
|
||||
void BuildIdHexstring<ELFT>::writeBuildId(ArrayRef<ArrayRef<uint8_t>> Bufs) {
|
||||
memcpy(this->HashBuf, Config->BuildIdVector.data(),
|
||||
Config->BuildIdVector.size());
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
MipsReginfoOutputSection<ELFT>::MipsReginfoOutputSection()
|
||||
: OutputSectionBase<ELFT>(".reginfo", SHT_MIPS_REGINFO, SHF_ALLOC) {
|
||||
|
|
@ -1852,5 +1862,10 @@ template class BuildIdSha1<ELF32LE>;
|
|||
template class BuildIdSha1<ELF32BE>;
|
||||
template class BuildIdSha1<ELF64LE>;
|
||||
template class BuildIdSha1<ELF64BE>;
|
||||
|
||||
template class BuildIdHexstring<ELF32LE>;
|
||||
template class BuildIdHexstring<ELF32BE>;
|
||||
template class BuildIdHexstring<ELF64LE>;
|
||||
template class BuildIdHexstring<ELF64BE>;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -581,6 +581,13 @@ public:
|
|||
void writeBuildId(ArrayRef<ArrayRef<uint8_t>> Bufs) override;
|
||||
};
|
||||
|
||||
template <class ELFT>
|
||||
class BuildIdHexstring final : public BuildIdSection<ELFT> {
|
||||
public:
|
||||
BuildIdHexstring();
|
||||
void writeBuildId(ArrayRef<ArrayRef<uint8_t>> Bufs) override;
|
||||
};
|
||||
|
||||
// All output sections that are hadnled by the linker specially are
|
||||
// globally accessible. Writer initializes them, so don't use them
|
||||
// until Writer is initialized.
|
||||
|
|
|
|||
|
|
@ -163,6 +163,8 @@ template <class ELFT> void elf::writeResult(SymbolTable<ELFT> *Symtab) {
|
|||
BuildId.reset(new BuildIdMd5<ELFT>);
|
||||
else if (Config->BuildId == BuildIdKind::Sha1)
|
||||
BuildId.reset(new BuildIdSha1<ELFT>);
|
||||
else if (Config->BuildId == BuildIdKind::Hexstring)
|
||||
BuildId.reset(new BuildIdHexstring<ELFT>);
|
||||
|
||||
if (Config->GnuHash)
|
||||
GnuHashTab.reset(new GnuHashTableSection<ELFT>);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@
|
|||
# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=MD5 %s
|
||||
# RUN: ld.lld --build-id=sha1 %t -o %t2
|
||||
# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=SHA1 %s
|
||||
# RUN: ld.lld --build-id=0x12345678 %t -o %t2
|
||||
# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=HEX %s
|
||||
# RUN: ld.lld %t -o %t2
|
||||
# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=NONE %s
|
||||
# RUN: ld.lld --build-id=md5 --build-id=none %t -o %t2
|
||||
|
|
@ -29,4 +31,8 @@ _start:
|
|||
# SHA1: Contents of section .note.gnu.build-id:
|
||||
# SHA1-NEXT: 04000000 14000000 03000000 474e5500 ............GNU.
|
||||
|
||||
# HEX: Contents of section .note.gnu.build-id:
|
||||
# HEX-NEXT: 04000000 04000000 03000000 474e5500 ............GNU.
|
||||
# HEX-NEXT: 12345678
|
||||
|
||||
# NONE-NOT: Contents of section .note.gnu.build-id:
|
||||
|
|
|
|||
Loading…
Reference in New Issue