1
1
mirror of https://github.com/rui314/mold.git synced 2024-11-15 04:10:40 +03:00
mold/elf/mapfile.cc

113 lines
3.0 KiB
C++
Raw Normal View History

2020-10-28 14:49:43 +03:00
#include "mold.h"
2020-10-29 06:24:54 +03:00
2021-03-15 18:53:53 +03:00
#include <fstream>
2020-12-10 16:32:47 +03:00
#include <iomanip>
#include <ios>
2021-04-29 10:33:31 +03:00
#include <sstream>
2021-03-15 19:11:55 +03:00
#include <tbb/parallel_for_each.h>
2020-12-12 14:34:13 +03:00
#include <unordered_map>
2020-10-29 06:24:54 +03:00
namespace mold::elf {
2021-03-29 14:29:57 +03:00
template <typename E>
2021-05-31 06:48:26 +03:00
using Map =
tbb::concurrent_hash_map<InputSection<E> *, std::vector<Symbol<E> *>>;
2021-04-29 11:54:16 +03:00
template <typename E>
static std::unique_ptr<std::ofstream> open_output_file(Context<E> &ctx) {
std::unique_ptr<std::ofstream> file(new std::ofstream);
2021-03-29 10:48:23 +03:00
file->open(ctx.arg.Map.c_str());
2021-03-15 18:53:53 +03:00
if (!file->is_open())
Fatal(ctx) << "cannot open " << ctx.arg.Map << ": " << errno_string();
2021-03-15 18:53:53 +03:00
return file;
}
2021-03-29 14:29:57 +03:00
template <typename E>
2021-04-29 11:54:16 +03:00
static Map<E> get_map(Context<E> &ctx) {
Map<E> map;
2021-03-15 19:11:55 +03:00
2021-03-29 14:29:57 +03:00
tbb::parallel_for_each(ctx.objs, [&](ObjectFile<E> *file) {
for (Symbol<E> *sym : file->symbols) {
2021-03-12 08:32:19 +03:00
if (sym->file == file && sym->input_section &&
2021-03-15 19:11:55 +03:00
sym->get_type() != STT_SECTION) {
2021-09-08 13:51:02 +03:00
assert(file == &sym->input_section->file);
2020-12-12 14:34:13 +03:00
2021-04-29 11:54:16 +03:00
typename Map<E>::accessor acc;
2021-03-15 19:11:55 +03:00
map.insert(acc, {sym->input_section, {}});
acc->second.push_back(sym);
}
}
});
2021-04-29 11:54:16 +03:00
tbb::parallel_for(map.range(), [](const typename Map<E>::range_type &range) {
2021-03-15 19:11:55 +03:00
for (auto it = range.begin(); it != range.end(); it++) {
2021-03-29 14:29:57 +03:00
std::vector<Symbol<E> *> &vec = it->second;
sort(vec, [](Symbol<E> *a, Symbol<E> *b) { return a->value < b->value; });
2021-03-15 19:11:55 +03:00
}
});
2021-04-29 11:54:16 +03:00
return map;
}
2021-03-15 19:11:55 +03:00
2021-04-29 11:54:16 +03:00
template <typename E>
void print_map(Context<E> &ctx) {
std::ostream *out = &std::cout;
std::unique_ptr<std::ofstream> file;
if (!ctx.arg.Map.empty()) {
file = open_output_file(ctx);
out = file.get();
}
// Construct a section-to-symbol map.
Map<E> map = get_map(ctx);
// Print a mapfile.
2021-03-15 19:11:55 +03:00
*out << " VMA Size Align Out In Symbol\n";
2020-10-29 06:24:54 +03:00
2021-10-04 04:16:24 +03:00
for (Chunk<E> *osec : ctx.chunks) {
2021-03-15 18:53:53 +03:00
*out << std::setw(16) << (u64)osec->shdr.sh_addr
2021-03-15 19:11:55 +03:00
<< std::setw(11) << (u64)osec->shdr.sh_size
2021-03-15 18:53:53 +03:00
<< std::setw(6) << (u64)osec->shdr.sh_addralign
<< " " << osec->name << "\n";
2020-10-29 06:24:54 +03:00
2021-10-04 04:16:24 +03:00
if (osec->kind != Chunk<E>::REGULAR)
2020-11-08 10:09:01 +03:00
continue;
2021-04-29 10:33:31 +03:00
std::span<InputSection<E> *> members = ((OutputSection<E> *)osec)->members;
std::vector<std::string> bufs(members.size());
2020-10-29 06:24:54 +03:00
2021-04-29 10:33:31 +03:00
tbb::parallel_for((i64)0, (i64)members.size(), [&](i64 i) {
InputSection<E> *mem = members[i];
std::ostringstream ss;
2021-04-29 11:54:16 +03:00
opt_demangle = ctx.arg.demangle;
2021-04-29 10:33:31 +03:00
ss << std::setw(16) << (osec->shdr.sh_addr + mem->offset)
<< std::setw(11) << (u64)mem->shdr.sh_size
<< std::setw(6) << (u64)mem->shdr.sh_addralign
<< " " << *mem << "\n";
2020-12-12 14:34:13 +03:00
2021-04-29 11:54:16 +03:00
typename Map<E>::const_accessor acc;
2021-04-29 10:33:31 +03:00
if (map.find(acc, mem))
for (Symbol<E> *sym : acc->second)
ss << std::setw(16) << sym->get_addr(ctx)
2021-03-15 19:11:55 +03:00
<< " 0 0 "
2021-03-15 18:53:53 +03:00
<< *sym << "\n";
2021-04-29 10:33:31 +03:00
bufs[i] = std::move(ss.str());
});
for (std::string &str : bufs)
*out << str;
2020-10-29 06:24:54 +03:00
}
}
2021-03-29 14:29:57 +03:00
#define INSTANTIATE(E) \
template void print_map(Context<E> &ctx);
INSTANTIATE(X86_64);
INSTANTIATE(I386);
INSTANTIATE(AARCH64);
} // namespace mold::elf