com.facebook.buck.cxx.elf.ElfDynamicSection.java Source code

Java tutorial

Introduction

Here is the source code for com.facebook.buck.cxx.elf.ElfDynamicSection.java

Source

/*
 * Copyright 2016-present Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may obtain
 * a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

package com.facebook.buck.cxx.elf;

import com.google.common.collect.ImmutableList;
import java.nio.ByteBuffer;
import java.util.Optional;

public class ElfDynamicSection {

    public final ImmutableList<Entry> entries;

    public ElfDynamicSection(ImmutableList<Entry> entries) {
        this.entries = entries;
    }

    public static ElfDynamicSection parse(ElfHeader.EIClass eiClass, ByteBuffer buffer) {
        ImmutableList.Builder<Entry> entries = ImmutableList.builder();
        while (buffer.hasRemaining()) {
            entries.add(Entry.parse(eiClass, buffer));
        }
        return new ElfDynamicSection(entries.build());
    }

    public void write(ElfHeader.EIClass eiClass, ByteBuffer buffer) {
        for (Entry entry : entries) {
            entry.write(eiClass, buffer);
        }
    }

    public Optional<Long> lookup(DTag dTag) {
        return entries.stream().filter(e -> e.d_tag == dTag).map(e -> e.d_un).findFirst();
    }

    public enum DTag {
        DT_NULL(0, Type.OTHER), DT_NEEDED(1, Type.STRING), DT_PLTRELSZ(2, Type.OTHER), DT_PLTGOT(3,
                Type.OTHER), DT_HASH(4, Type.OTHER), DT_STRTAB(5, Type.OTHER), DT_SYMTAB(6, Type.OTHER), DT_RELA(7,
                        Type.OTHER), DT_RELASZ(8, Type.OTHER), DT_RELAENT(9, Type.OTHER), DT_STRSZ(10,
                                Type.OTHER), DT_SYMENT(11, Type.OTHER), DT_INIT(12, Type.OTHER), DT_FINI(13,
                                        Type.OTHER), DT_SONAME(14, Type.STRING), DT_RPATH(15,
                                                Type.STRING), DT_SYMBOLIC(16, Type.OTHER), DT_REL(17,
                                                        Type.OTHER), DT_RELSZ(18, Type.OTHER), DT_RELENT(19,
                                                                Type.OTHER), DT_PLTREL(20, Type.OTHER), DT_DEBUG(21,
                                                                        Type.OTHER), DT_TEXTREL(22,
                                                                                Type.OTHER), DT_JMPREL(23,
                                                                                        Type.OTHER), DT_BIND_NOW(24,
                                                                                                Type.OTHER), DT_INIT_ARRAY(
                                                                                                        25,
                                                                                                        Type.OTHER), DT_FINI_ARRAY(
                                                                                                                26,
                                                                                                                Type.OTHER), DT_INIT_ARRAYSZ(
                                                                                                                        27,
                                                                                                                        Type.OTHER), DT_FINI_ARRAYSZ(
                                                                                                                                28,
                                                                                                                                Type.OTHER), DT_RUNPATH(
                                                                                                                                        29,
                                                                                                                                        Type.STRING), DT_FLAGS(
                                                                                                                                                30,
                                                                                                                                                Type.OTHER), DT_GNU_HASH(
                                                                                                                                                        0x6ffffef5,
                                                                                                                                                        Type.OTHER), DT_VERSYM(
                                                                                                                                                                0x6ffffff0,
                                                                                                                                                                Type.OTHER), DT_RELACOUNT(
                                                                                                                                                                        0x6ffffff9,
                                                                                                                                                                        Type.OTHER), DT_RELCOUNT(
                                                                                                                                                                                0x6ffffffa,
                                                                                                                                                                                Type.OTHER), DT_FLAGS_1(
                                                                                                                                                                                        0x6ffffffb,
                                                                                                                                                                                        Type.OTHER), DT_VERDEF(
                                                                                                                                                                                                0x6ffffffc,
                                                                                                                                                                                                Type.OTHER), DT_VERDEFNUM(
                                                                                                                                                                                                        0x6ffffffd,
                                                                                                                                                                                                        Type.OTHER), DT_VERNEED(
                                                                                                                                                                                                                0x6ffffffe,
                                                                                                                                                                                                                Type.OTHER), DT_VERNEEDNUM(
                                                                                                                                                                                                                        0x6fffffff,
                                                                                                                                                                                                                        Type.OTHER),;

        private final int value;
        private final Type type;

        DTag(int value, Type type) {
            this.value = value;
            this.type = type;
        }

        public static DTag valueOf(int val) {
            for (DTag clazz : DTag.values()) {
                if (clazz.value == val) {
                    return clazz;
                }
            }
            throw new IllegalArgumentException(String.format("unknown dynamic tag: %s", val));
        }

        public int getValue() {
            return value;
        }

        public Type getType() {
            return type;
        }

        public enum Type {
            STRING, OTHER,
        }
    }

    public static class Entry {

        public final DTag d_tag;
        public final long d_un;

        public Entry(DTag d_tag, long d_un) {
            this.d_tag = d_tag;
            this.d_un = d_un;
        }

        private static Entry parse(ElfHeader.EIClass eiClass, ByteBuffer buffer) {
            if (eiClass == ElfHeader.EIClass.ELFCLASS32) {
                return new Entry(DTag.valueOf(Elf.Elf32.getElf32Sword(buffer)), Elf.Elf32.getElf32Addr(buffer));
            } else {
                return new Entry(DTag.valueOf((int) Elf.Elf64.getElf64Sxword(buffer)),
                        Elf.Elf64.getElf64Addr(buffer));
            }
        }

        private void write(ElfHeader.EIClass eiClass, ByteBuffer buffer) {
            if (eiClass == ElfHeader.EIClass.ELFCLASS32) {
                Elf.Elf32.putElf32Sword(buffer, d_tag.value);
                Elf.Elf32.putElf32Addr(buffer, (int) d_un);
            } else {
                Elf.Elf64.putElf64Sxword(buffer, d_tag.value);
                Elf.Elf64.putElf64Addr(buffer, d_un);
            }
        }
    }
}