blob: 63af82d8548001d0b3bbaf0aa60808aeaa0d599a [file] [log] [blame]
// Copyright 2018 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 "dynlink.h"
LIBC_NO_SAFESTACK NO_ASAN static inline void apply_relr(ElfW(Addr) base, const ElfW(Addr) * relr,
size_t relrsz) {
const size_t nrelr = relrsz / sizeof(relr[0]);
size_t i = 0;
while (i < nrelr) {
ElfW(Addr)* addr = (void*)(base + relr[i++]);
*addr++ += base;
while (i < nrelr && (relr[i] & 1)) {
// Each bitmask word covers the next 63 possible relocations.
// Each bit is one if run[bit] should be relocated.
ElfW(Addr)* run = addr;
addr += (sizeof(relr[0]) * CHAR_BIT) - 1;
int skip;
for (ElfW(Addr) bitmask = relr[i++] >> 1; bitmask != 0; bitmask >>= skip) {
skip = __builtin_ctzl(bitmask) + 1;
run += skip;
run[-1] += base;
}
}
}
}