// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <string>

namespace {

#define BUILDSIG_START_MAGIC UINT64_C(0x5452545347495342) // BSIGSTRT
#define BUILDSIG_END_MAGIC UINT64_C(0x53444e4547495342)   // BSIGENDS
struct buildsig {
    uint64_t start_magic;
    uint64_t buildsig_address;
    uint64_t lk_version_address;
    uint64_t note_address;
    uint64_t end_magic;
};

#define LK_VERSION_STRUCT_VERSION 0x2
struct lk_version {
    uint32_t struct_version;
    uint32_t pad;
    uint64_t arch;
    uint64_t platform;
    uint64_t target;
    uint64_t project;
    uint64_t buildid;
};

#define ELF_BUILDID_NOTE_NAME "GNU"
#define ELF_BUILDID_NOTE_NAMESZ (sizeof("GNU"))
#define ELF_BUILDID_NOTE_TYPE 3
struct elf_buildid_note {
    uint32_t namesz;
    uint32_t descsz;
    uint32_t type;
    char name[(ELF_BUILDID_NOTE_NAMESZ + 3) & ~3];
};

class reader {
public:
    reader(FILE* input)
        : input_(input) {}

    bool scan() {
        pos_ = 0;
        do {
            if (consider()) {
                print();
                return true;
            }
            pos_ += 8;
        } while (fseek(input_, pos_, SEEK_SET) == 0);
        return false;
    }

private:
    FILE* input_;
    long int pos_;
    buildsig sig_;
    bool needs_byteswap_;

    static const int indent = 4;
    class extracted_item {
    public:
        extracted_item(const char* name)
            : name_(name) {}

        const char* name() const { return name_; }
        std::string* contents() { return &contents_; }
        const std::string* contents() const { return &contents_; }

        void print(bool last = false) const {
            printf("%*s{\"%s\": \"%s\"}%s\n",
                   indent, "", name(), contents()->c_str(),
                   last ? "" : ",");
        }

    private:
        const char* name_;
        std::string contents_;
    };

    extracted_item arch_{"arch"};
    extracted_item platform_{"platform"};
    extracted_item target_{"target"};
    extracted_item project_{"project"};
    extracted_item buildid_{"buildid"};
    extracted_item elf_buildid_{"elf_build_id"};

    void print() const {
        puts("{");
        arch_.print();
        platform_.print();
        target_.print();
        project_.print();
        buildid_.print();
        elf_buildid_.print(true);
        puts("}");
    }

    static uint64_t byteswap_constant(uint64_t constant) {
        return __builtin_bswap64(constant);
    }

    void byteswap(uint64_t* x) {
        if (needs_byteswap_)
            *x = __builtin_bswap64(*x);
    }

    void byteswap(uint32_t* x) {
        if (needs_byteswap_)
            *x = __builtin_bswap32(*x);
    }

    bool consider() {
        if (fread(&sig_, sizeof(sig_), 1, input_) == 1) {
            if (sig_.start_magic == BUILDSIG_START_MAGIC &&
                sig_.end_magic == BUILDSIG_END_MAGIC) {
                needs_byteswap_ = false;
                return decode();
            }
            if (sig_.start_magic == byteswap_constant(BUILDSIG_START_MAGIC) &&
                sig_.end_magic == byteswap_constant(BUILDSIG_END_MAGIC)) {
                needs_byteswap_ = true;
                return decode();
            }
        }
        return false;
    }

    bool decode() {
        byteswap(&sig_.buildsig_address);

        lk_version version;
        if (!read_from_address(sig_.lk_version_address,
                               &version, sizeof(version)))
            return false;
        byteswap(&version.struct_version);
        if (version.struct_version != LK_VERSION_STRUCT_VERSION)
            return false;

        return (read_string_from_address(version.arch, &arch_) &&
                read_string_from_address(version.platform, &platform_) &&
                read_string_from_address(version.target, &target_) &&
                read_string_from_address(version.project, &project_) &&
                read_string_from_address(version.buildid, &buildid_) &&
                handle_buildid_note(sig_.note_address));
    }

    bool read_from_address(uint64_t address, void* buf, size_t size) {
        return seek_to_address(address) && fread(buf, size, 1, input_) == 1;
    }

    bool read_string_from_address(uint64_t address, extracted_item* item) {
        if (seek_to_address(address)) {
            char* buf = NULL;
            size_t size = 0;
            if (getdelim(&buf, &size, '\0', input_) > 0) {
                *item->contents() = buf;
                free(buf);
                return true;
            }
        }
        return false;
    }

    bool seek_to_address(uint64_t address) {
        byteswap(&address);
        if (address > sig_.buildsig_address) {
            address -= sig_.buildsig_address;
            address += pos_;
            return (fseek(input_, address, SEEK_SET) == 0 &&
                    static_cast<uint64_t>(ftell(input_)) == address);
        }
        return false;
    }

    bool handle_buildid_note(uint64_t address) {
        elf_buildid_note note;
        if (read_from_address(address, &note, sizeof(note))) {
            byteswap(&note.namesz);
            byteswap(&note.descsz);
            byteswap(&note.type);
            if (note.namesz == ELF_BUILDID_NOTE_NAMESZ &&
                note.type == ELF_BUILDID_NOTE_TYPE &&
                !memcmp(note.name, ELF_BUILDID_NOTE_NAME,
                        ELF_BUILDID_NOTE_NAMESZ)) {
                auto desc = std::make_unique<uint8_t[]>(note.descsz);
                if (fread(desc.get(), note.descsz, 1, input_) == 1) {
                    std::string* text = elf_buildid_.contents();
                    text->clear();
                    for (uint32_t i = 0; i < note.descsz; ++i) {
                        char buf[3] = "XX";
                        snprintf(buf, sizeof(buf), "%02x", desc[i]);
                        *text += buf;
                    }
                    return true;
                }
            }
        }
        return false;
    }
};

} // anonymous namespace

int main(int argc, char* argv[]) {
    const char* filename;
    FILE* input;
    switch (argc) {
    case 1:
        filename = "<standard input>";
        input = stdin;
        break;
    case 2:
        filename = argv[1];
        input = fopen(filename, "rb");
        if (!input) {
            fprintf(stderr, "%s: %s: %s\n",
                    argv[0], filename, strerror(errno));
            return 2;
        }
        break;
    default:
        fprintf(stderr, "Usage: %s [FILENAME]\n", argv[0]);
        return 1;
    }

    if (reader{input}.scan())
        return 0;

    if (ferror(input)) {
        fprintf(stderr, "%s: %s: %s\n",
                argv[0], filename, strerror(errno));
    } else {
        fprintf(stderr, "%s: %s: Cannot find a signature\n",
                argv[0], filename);
    }
    return 2;
}
