[PATCH] D89432: [llvm-elfabi] Emit ELF .dynsym and .dynamic sections
George Rimar via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 26 23:10:06 PDT 2020
grimar added inline comments.
================
Comment at: llvm/lib/InterfaceStub/ELFObjHandler.cpp:119
+
+ void add(ELFStringTableBuilder &StrTabBuilder, StringRef StName,
+ uint64_t StSize, uint8_t StBind, uint8_t StType, uint8_t StOther,
----------------
Instead of passing both `StrTabBuilder` abd `StName` you can just pass an offset.
================
Comment at: llvm/lib/InterfaceStub/ELFObjHandler.cpp:113
+
+public:
+ ELFSymbolTableBuilder() {
----------------
haowei wrote:
> grimar wrote:
> > You can avoid having 2 `public:` areas by merging them.
> The private section needs the "Elf_Sym" type alias declared in the first public section and the second public section requires the private "Symbols" variable. So I don't think I can merge the two public sections as it is a chicken and egg issue.
There is no chicken and egg issue here. C++ doesn't work like that.
You don`t have ro declare the `Symbols` member before using it in member functions.
So, you can do the following:
```
template <class ELFT> class ELFSymbolTableBuilder {
public:
using Elf_Sym = typename ELFT::Sym;
ELFSymbolTableBuilder() {
Elf_Sym S{};
Symbols.push_back(S);
}
void add(ELFStringTableBuilder &StrTabBuilder, StringRef StName,
uint64_t StSize, uint8_t StBind, uint8_t StType, uint8_t StOther,
uint16_t StShndx) {
Elf_Sym S{};
S.st_name = StrTabBuilder.getOffset(StName);
S.st_size = StSize;
S.st_info = (StBind << 4) | (StType & 0xf);
S.st_other = StOther;
S.st_shndx = StShndx;
Symbols.push_back(S);
}
size_t getSize() const { return Symbols.size() * sizeof(Elf_Sym); }
void write(uint8_t *Buf) const {
memcpy(Buf, Symbols.data(), sizeof(Elf_Sym) * Symbols.size());
}
private:
llvm::SmallVector<Elf_Sym, 64> Symbols;
};
```
================
Comment at: llvm/lib/InterfaceStub/ELFObjHandler.cpp:195
+ sizeof(Elf_Dyn));
+ }
+};
----------------
haowei wrote:
> grimar wrote:
> > If you add `DT_NULL` explicitly in the code, then you can simplify these 2 methods to:
> >
> >
> > ```
> > size_t getSize() const { return Entries.size() * sizeof(Elf_Dyn); }
> >
> > void write(uint8_t *Buf) const { memcpy(Buf, Entries.data(), getSize()); }
> > ```
> >
> >
> >
> I prefer to keep "add DT_NULL" in the builder class instead of explicitly in the code. It reduces the chance a maintainer add new entries after DT_NULL entry in the future.
I think, this is a design issue. With this approach `Entries` doesn't contain all entries written.
`DT_NULL` is a terminator entry, but it is still an entry.
Though, if you want go this way, then you should be able to use `memset`:
`memset(Buf + sizeof(Elf_Dyn) * Entries.size(), 0, sizeof(Elf_Dyn));`
instead of
```
constexpr Elf_Dyn Terminator{};
memcpy(Buf + sizeof(Elf_Dyn) * Entries.size(), &Terminator,
sizeof(Elf_Dyn));
```
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D89432/new/
https://reviews.llvm.org/D89432
More information about the llvm-commits
mailing list