std::unique_ptr<TarWriter> elf::tar;
+DenseMap<StringRef, StringRef> elf::gnuWarnings;
+
// Returns "<internal>", "foo.a(bar.o)" or "baz.o".
std::string lld::toString(const InputFile *f) {
if (!f)
return f->toStringCache;
}
+// .gnu.warning.SYMBOL are treated as warning symbols for the given symbol
+void lld::parseGNUWarning(StringRef name, ArrayRef<char> data, size_t size) {
+ if (!name.empty() && name.startswith(".gnu.warning.")) {
+ StringRef wsym = name.substr(13);
+ StringRef s(data.begin());
+ StringRef wng(s.substr(0, size));
+ symtab->insert(wsym)->gwarn = true;
+ gnuWarnings.insert({wsym, wng});
+ }
+}
+
static ELFKind getELFKind(MemoryBufferRef mb, StringRef archiveName) {
unsigned char size;
unsigned char endian;
case SHT_RELA:
case SHT_NULL:
break;
+ case SHT_PROGBITS: {
+ this->sections[i] = createInputSection(sec);
+ StringRef name = CHECK(obj.getSectionName(sec, this->sectionStringTable), this);
+ ArrayRef<char> data =
+ CHECK(obj.template getSectionContentsAsArray<char>(sec), this);
+ parseGNUWarning(name, data, sec.sh_size);
+ }
+ break;
default:
this->sections[i] = createInputSection(sec);
}
const ELFFile<ELFT> obj = this->getObj<ELFT>();
ArrayRef<Elf_Shdr> sections = CHECK(obj.sections(), this);
+ StringRef sectionStringTable =
+ CHECK(obj.getSectionStringTable(sections), this);
+
const Elf_Shdr *versymSec = nullptr;
const Elf_Shdr *verdefSec = nullptr;
const Elf_Shdr *verneedSec = nullptr;
case SHT_GNU_verneed:
verneedSec = &sec;
break;
+ case SHT_PROGBITS: {
+ StringRef name = CHECK(obj.getSectionName(sec, sectionStringTable), this);
+ ArrayRef<char> data =
+ CHECK(obj.template getSectionContentsAsArray<char>(sec), this);
+ parseGNUWarning(name, data, sec.sh_size);
+ break;
+ }
}
}
// Returns "<internal>", "foo.a(bar.o)" or "baz.o".
std::string toString(const elf::InputFile *f);
+void parseGNUWarning(StringRef name, ArrayRef<char> data, size_t size);
+
namespace elf {
using llvm::object::Archive;
undefs.clear();
}
+static void reportGNUWarning(Symbol &sym, InputSectionBase &sec,
+ uint64_t offset) {
+ if (sym.gwarn) {
+ StringRef gnuWarning = gnuWarnings.lookup(sym.getName());
+ // report first occurance only
+ sym.gwarn = false;
+ if (!gnuWarning.empty())
+ message(sec.getSrcMsg(sym, offset) + "(" + sec.getObjMsg(offset) +
+ "): warning: " + gnuWarning);
+ }
+}
+
// Report an undefined symbol if necessary.
// Returns true if the undefined symbol will produce an error message.
static bool maybeReportUndefined(Symbol &sym, InputSectionBase &sec,
if (symIndex != 0 && maybeReportUndefined(sym, sec, rel.r_offset))
return;
+ reportGNUWarning(sym, sec, rel.r_offset);
+
const uint8_t *relocatedAddr = sec.data().begin() + rel.r_offset;
RelExpr expr = target->getRelExpr(type, sym, relocatedAddr);
sym->canInline = true;
sym->referenced = false;
sym->traced = false;
+ sym->gwarn = false;
sym->scriptDefined = false;
sym->partition = 1;
return sym;
// True if this symbol is specified by --trace-symbol option.
uint8_t traced : 1;
+ // True if the .gnu.warning.SYMBOL is set for the symbol
+ uint8_t gwarn : 1;
+
inline void replace(const Symbol &newSym);
bool includeInDynsym() const;
type(type), stOther(stOther), symbolKind(k), visibility(stOther & 3),
isUsedInRegularObj(!file || file->kind() == InputFile::ObjKind),
exportDynamic(isExportDynamic(k, visibility)), inDynamicList(false),
- canInline(false), referenced(false), traced(false), needsPltAddr(false),
+ canInline(false), referenced(false), traced(false), gwarn(false), needsPltAddr(false),
isInIplt(false), gotInIgot(false), isPreemptible(false),
used(!config->gcSections), needsTocRestore(false),
scriptDefined(false) {}
canInline = old.canInline;
referenced = old.referenced;
traced = old.traced;
+ gwarn = old.gwarn;
isPreemptible = old.isPreemptible;
scriptDefined = old.scriptDefined;
partition = old.partition;
bool computeIsPreemptible(const Symbol &sym);
void reportBackrefs();
+extern llvm::DenseMap<StringRef, StringRef> gnuWarnings;
+
// A mapping from a symbol to an InputFile referencing it backward. Used by
// --warn-backrefs.
extern llvm::DenseMap<const Symbol *,