Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
rui314 committed Oct 20, 2024
1 parent 9cf1165 commit 0841ffc
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 38 deletions.
23 changes: 20 additions & 3 deletions src/mold.h
Original file line number Diff line number Diff line change
Expand Up @@ -1028,9 +1028,22 @@ class NotePropertySection : public Chunk<E> {
void copy_buf(Context<E> &ctx) override;

private:
static constexpr i64 ENTRY_SIZE = E::is_64 ? 16 : 12;
struct Entry64 {
ul32 type;
ul32 size;
ul32 flags;
u32 padding;
};

struct Entry32 {
ul32 type;
ul32 size;
ul32 flags;
};

std::map<u32, u32> properties;
using Entry = std::conditional_t<E::is_64, Entry64, Entry32>;

std::vector<Entry> contents;
};

template <typename E>
Expand Down Expand Up @@ -1809,6 +1822,11 @@ struct SectionOrder {
template <typename E>
struct ContextExtras {};

template <is_x86 E>
struct ContextExtras<E> {
NotePropertySection<E> *note_property = nullptr;
};

template <>
struct ContextExtras<ARM32> {
Arm32ExidxSection *exidx = nullptr;
Expand Down Expand Up @@ -2080,7 +2098,6 @@ struct Context {
VerdefSection<E> *verdef = nullptr;
BuildIdSection<E> *buildid = nullptr;
NotePackageSection<E> *note_package = nullptr;
NotePropertySection<E> *note_property = nullptr;
GdbIndexSection<E> *gdb_index = nullptr;
RelroPaddingSection<E> *relro_padding = nullptr;
MergedSection<E> *comment = nullptr;
Expand Down
54 changes: 21 additions & 33 deletions src/output-chunks.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2760,12 +2760,7 @@ void NotePackageSection<E>::copy_buf(Context<E> &ctx) {
// Merges input files' .note.gnu.property values.
template <typename E>
void NotePropertySection<E>::update_shdr(Context<E> &ctx) {
// The rules we support are only specified for x86 psABI
if (!is_x86<E>)
return;

// Reset to the initial state so that this function is idempotent
properties.clear();
std::map<u32, u32> map;

// Obtain the list of keys
std::vector<ObjectFile<E> *> files = ctx.objs;
Expand Down Expand Up @@ -2793,60 +2788,53 @@ void NotePropertySection<E>::update_shdr(Context<E> &ctx) {
key <= GNU_PROPERTY_X86_UINT32_AND_HI) {
// An AND feature is set if all input objects have the property and
// the feature.
if (std::all_of(files.begin(), files.end(), has_key)) {
properties[key] = 0xffff'ffff;
for (ObjectFile<E> *file : files)
properties[key] &= get_value(file, key);
}
map[key] = 0xffff'ffff;
for (ObjectFile<E> *file : files)
map[key] &= get_value(file, key);
} else if (GNU_PROPERTY_X86_UINT32_OR_LO <= key &&
key <= GNU_PROPERTY_X86_UINT32_OR_HI) {
// An OR feature is set if some input object has the feature.
for (ObjectFile<E> *file : files)
properties[key] |= get_value(file, key);
map[key] |= get_value(file, key);
} else if (GNU_PROPERTY_X86_UINT32_OR_AND_LO <= key &&
key <= GNU_PROPERTY_X86_UINT32_OR_AND_HI) {
// An OR-AND feature is set if all input object files have the property
// and some of them has the feature.
if (std::all_of(files.begin(), files.end(), has_key))
for (ObjectFile<E> *file : files)
properties[key] |= get_value(file, key);
map[key] |= get_value(file, key);
}
}

if (ctx.arg.z_ibt)
properties[GNU_PROPERTY_X86_FEATURE_1_AND] |= GNU_PROPERTY_X86_FEATURE_1_IBT;
map[GNU_PROPERTY_X86_FEATURE_1_AND] |= GNU_PROPERTY_X86_FEATURE_1_IBT;
if (ctx.arg.z_shstk)
properties[GNU_PROPERTY_X86_FEATURE_1_AND] |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
map[GNU_PROPERTY_X86_FEATURE_1_AND] |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
map[GNU_PROPERTY_X86_ISA_1_NEEDED] |= ctx.arg.z_x86_64_isa_level;

properties[GNU_PROPERTY_X86_ISA_1_NEEDED] |= ctx.arg.z_x86_64_isa_level;
// Serialize the map
contents.clear();

std::erase_if(properties, [](std::pair<u32, u32> kv) {
return kv.second == 0;
});
for (std::pair<u32, u32> kv : map)
if (kv.second)
contents.push_back({kv.first, 4, kv.second});

if (properties.empty())
if (contents.empty())
this->shdr.sh_size = 0;
else
this->shdr.sh_size = 16 + ENTRY_SIZE * properties.size();
this->shdr.sh_size = 16 + contents.size() * sizeof(contents[0]);
}

template <typename E>
void NotePropertySection<E>::copy_buf(Context<E> &ctx) {
U32<E> *buf = (U32<E> *)(ctx.buf + this->shdr.sh_offset);
memset(buf, 0, this->shdr.sh_size);

buf[0] = 4; // Name size
buf[1] = ENTRY_SIZE * properties.size(); // Content size
buf[2] = NT_GNU_PROPERTY_TYPE_0; // Type
memcpy(buf + 3, "GNU", 4); // Name

i64 idx = 4;
for (std::pair<u32, u32> kv : properties) {
buf[idx] = kv.first; // Feature type
buf[idx + 1] = 4; // Feature size
buf[idx + 2] = kv.second; // Feature flags
idx += ENTRY_SIZE / sizeof(U32<E>);
}
buf[0] = 4; // Name size
buf[1] = this->shdr.sh_size - 16; // Content size
buf[2] = NT_GNU_PROPERTY_TYPE_0; // Type
memcpy(buf + 3, "GNU", 4); // Name
write_vector(buf + 4, contents); // Content
}

template <typename E>
Expand Down
4 changes: 3 additions & 1 deletion src/passes.cc
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,6 @@ void create_synthetic_sections(Context<E> &ctx) {
ctx.versym = push(new VersymSection<E>);
ctx.verneed = push(new VerneedSection<E>);
ctx.note_package = push(new NotePackageSection<E>);
ctx.note_property = push(new NotePropertySection<E>);

if (!ctx.arg.oformat_binary) {
ElfShdr<E> shdr = {};
Expand All @@ -185,6 +184,9 @@ void create_synthetic_sections(Context<E> &ctx) {
ctx.comment = MergedSection<E>::get_instance(ctx, ".comment", shdr);
}

if constexpr (is_x86<E>)
ctx.extra.note_property = push(new NotePropertySection<E>);

if constexpr (is_riscv<E>)
ctx.extra.riscv_attributes = push(new RiscvAttributesSection<E>);

Expand Down
4 changes: 3 additions & 1 deletion src/relocatable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ static void r_create_synthetic_sections(Context<E> &ctx) {
ctx.strtab = push(new StrtabSection<E>);
ctx.symtab = push(new SymtabSection<E>);
ctx.shstrtab = push(new ShstrtabSection<E>);
ctx.note_property = push(new NotePropertySection<E>);

if constexpr (is_x86<E>)
ctx.extra.note_property = push(new NotePropertySection<E>);

if constexpr (is_riscv<E>)
ctx.extra.riscv_attributes = push(new RiscvAttributesSection<E>);
Expand Down

0 comments on commit 0841ffc

Please sign in to comment.