#include <stdio.h>
#include <elfcap.h>
#include <sys/sysmacros.h>
#include <stdlib.h>
#define ECS_UNKNOWN 10
typedef const elfcap_desc_t *(*elfcap_getdesc_f)(void);
typedef struct elfcap_getdesc {
uint32_t eg_nents;
elfcap_getdesc_f eg_func;
} elfcap_getdesc_t;
#define NUM_PLATS 2
typedef struct elfcap_case {
const char *ec_tag;
size_t ec_header;
elfcap_getdesc_t ec_descs[NUM_PLATS];
} elfcap_case_t;
const elfcap_case_t elfcaps[] = {
{ "ELFCAP_SF1_BUFSIZE", ELFCAP_SF1_BUFSIZE, {
{ ELFCAP_NUM_SF1, elfcap_getdesc_sf1 },
{ 0, NULL }
} },
{ "ELFCAP_HW1_BUFSIZE", ELFCAP_HW1_BUFSIZE, {
{ ELFCAP_NUM_HW1_386, elfcap_getdesc_hw1_386 },
{ ELFCAP_NUM_HW1_SPARC, elfcap_getdesc_hw1_sparc }
} },
{ "ELFCAP_HW2_BUFSIZE", ELFCAP_HW2_BUFSIZE, {
{ ELFCAP_NUM_HW2_386, elfcap_getdesc_hw2_386 },
{ 0, NULL }
} },
{ "ELFCAP_HW3_BUFSIZE", ELFCAP_HW3_BUFSIZE, {
{ ELFCAP_NUM_HW3_386, elfcap_getdesc_hw3_386 },
{ 0, NULL }
} },
};
static size_t
elfcap_calc_len(const elfcap_desc_t *desc, uint32_t nents, size_t space)
{
size_t len = 0;
for (uint32_t i = 0; i < nents; i++) {
len += desc[i].c_full.s_len;
if (i > 0) {
len += space;
}
}
if (nents < 32) {
len += space + ECS_UNKNOWN;
}
len += 9;
return (len);
}
static size_t
elfcap_max_len(const elfcap_case_t *ec, size_t slen)
{
size_t max = 0;
for (size_t i = 0; i < ARRAY_SIZE(ec->ec_descs); i++) {
const elfcap_desc_t *desc;
size_t len;
if (ec->ec_descs[i].eg_func == NULL)
continue;
desc = ec->ec_descs[i].eg_func();
len = elfcap_calc_len(desc, ec->ec_descs[i].eg_nents, slen);
if (len > max)
max = len;
}
return (max);
}
int
main(void)
{
size_t slen;
const elfcap_str_t *strs;
int ret = EXIT_SUCCESS;
strs = elfcap_getdesc_formats();
slen = strs[ELFCAP_FMT_PIPSPACE].s_len;
for (size_t i = 0; i < ARRAY_SIZE(elfcaps); i++) {
size_t out = elfcap_max_len(&elfcaps[i], slen);
if (out != elfcaps[i].ec_header) {
(void) fprintf(stderr, "elfcap size for %s is not "
"expected value!\n\tCurrent value is %zu, should "
"be %zu\n", elfcaps[i].ec_tag, elfcaps[i].ec_header,
out);
ret = EXIT_FAILURE;
}
}
if (ret != EXIT_SUCCESS) {
(void) fprintf(stderr, "please update $SRC/common/elfcap/"
"elfcap.h and $SRC/cmd/sgs/include/conv.h with the new "
"values reported above\n");
}
return (ret);
}